// 网络请求封装
import { API_BASE_URL, REQUEST_TIMEOUT, ERROR_CODES, ERROR_MESSAGES } from './constants.js'

// 请求拦截器
const requestInterceptor = (options) => {
  // 添加基础URL
  if (!options.url.startsWith('http')) {
    options.url = API_BASE_URL + options.url
  }

  // 添加超时时间
  options.timeout = options.timeout || REQUEST_TIMEOUT

  // 添加请求头
  options.header = {
    'Content-Type': 'application/json',
    ...options.header
  }

  // 添加认证token
  const token = wx.getStorageSync('token')
  if (token) {
    options.header.Authorization = `Bearer ${token}`
  }

  return options
}

// 响应拦截器
const responseInterceptor = (response) => {
  const { statusCode, data } = response

  // HTTP状态码检查
  if (statusCode >= 200 && statusCode < 300) {
    // 业务状态码检查
    if (data.code === ERROR_CODES.SUCCESS) {
      return Promise.resolve(data)
    } else {
      // 业务错误处理
      const errorMsg = data.msg || ERROR_MESSAGES[data.code] || '请求失败'
      wx.showToast({
        title: errorMsg,
        icon: 'none',
        duration: 2000
      })
      return Promise.reject(new Error(errorMsg))
    }
  } else {
    // HTTP错误处理
    let errorMsg = '网络请求失败'
    switch (statusCode) {
      case 401:
        errorMsg = '未授权，请重新登录'
        // 清除本地token
        wx.removeStorageSync('token')
        wx.removeStorageSync('userInfo')
        // 跳转到登录页
        wx.navigateTo({
          url: '/pages/login/login'
        })
        break
      case 403:
        errorMsg = '权限不足'
        break
      case 404:
        errorMsg = '请求的资源不存在'
        break
      case 500:
        errorMsg = '服务器内部错误'
        break
      default:
        errorMsg = `请求失败 (${statusCode})`
    }
    
    wx.showToast({
      title: errorMsg,
      icon: 'none',
      duration: 2000
    })
    
    return Promise.reject(new Error(errorMsg))
  }
}

// 请求方法封装
const request = (options) => {
  return new Promise((resolve, reject) => {
    // 请求拦截
    const interceptedOptions = requestInterceptor(options)

    // 显示加载提示
    if (options.loading !== false) {
      wx.showLoading({
        title: options.loadingText || '加载中...',
        mask: true
      })
    }

    wx.request({
      ...interceptedOptions,
      success: (response) => {
        // 隐藏加载提示
        if (options.loading !== false) {
          wx.hideLoading()
        }

        // 响应拦截
        responseInterceptor(response)
          .then(resolve)
          .catch(reject)
      },
      fail: (error) => {
        // 隐藏加载提示
        if (options.loading !== false) {
          wx.hideLoading()
        }

        // 网络错误处理
        let errorMsg = '网络连接失败'
        if (error.errMsg) {
          if (error.errMsg.includes('timeout')) {
            errorMsg = '请求超时，请检查网络连接'
          } else if (error.errMsg.includes('fail')) {
            errorMsg = '网络请求失败'
          }
        }

        wx.showToast({
          title: errorMsg,
          icon: 'none',
          duration: 2000
        })

        reject(new Error(errorMsg))
      }
    })
  })
}

// GET请求
export const get = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'GET',
    data,
    ...options
  })
}

// POST请求
export const post = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'POST',
    data,
    ...options
  })
}

// PUT请求
export const put = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'PUT',
    data,
    ...options
  })
}

// DELETE请求
export const del = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'DELETE',
    data,
    ...options
  })
}

// 文件上传
export const upload = (url, filePath, formData = {}, options = {}) => {
  return new Promise((resolve, reject) => {
    // 显示上传进度
    if (options.loading !== false) {
      wx.showLoading({
        title: '上传中...',
        mask: true
      })
    }

    const token = wx.getStorageSync('token')
    const header = {
      'Authorization': token ? `Bearer ${token}` : '',
      ...options.header
    }

    wx.uploadFile({
      url: API_BASE_URL + url,
      filePath,
      name: options.name || 'file',
      formData,
      header,
      success: (response) => {
        // 隐藏上传进度
        if (options.loading !== false) {
          wx.hideLoading()
        }

        try {
          const data = JSON.parse(response.data)
          if (data.code === ERROR_CODES.SUCCESS) {
            resolve(data)
          } else {
            const errorMsg = data.msg || '上传失败'
            wx.showToast({
              title: errorMsg,
              icon: 'none',
              duration: 2000
            })
            reject(new Error(errorMsg))
          }
        } catch (error) {
          wx.showToast({
            title: '上传失败',
            icon: 'none',
            duration: 2000
          })
          reject(new Error('上传失败'))
        }
      },
      fail: (error) => {
        // 隐藏上传进度
        if (options.loading !== false) {
          wx.hideLoading()
        }

        wx.showToast({
          title: '上传失败',
          icon: 'none',
          duration: 2000
        })
        reject(new Error('上传失败'))
      }
    })
  })
}

export default {
  get,
  post,
  put,
  delete: del,
  upload
}
